﻿using EquipViewAppNet;
using EquipSecs300;
using EquipSecs300.Parameter;
using SecsEquip;
using SecsEquip300;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics.Eventing.Reader;

namespace EquipSecs300
{
    public class GEM_PJob : SecsEquipEx
    {
        public string m_pViewName;
        public List<ProcessJob> PJobListAll { get; set; }
        public List<ProcessJob> PJobListByCJob { get; set; }
        public ProcessJob CurSelPJob { get; set; }
        public string CurSelPJobID { get; set; }

        public OnPJobCreateHandler m_pOnPJobCreateView;
        public Action PJobStageChange;

        private int _pJobUnusedCount;
        private int _pJobCount;

        public int PJobUnusedCount
        {
            get
            {
                _pJobUnusedCount = 0;
                for (int i = 0; i < PJobListAll.Count; i++)
                {
                    if (PJobListAll[i].nPRJobState == ProcessJobState.QUEUED)
                    {
                        _pJobUnusedCount++;
                    }
                }
                return _pJobUnusedCount;
            }
        }
        public int PJobCount
        {
            get
            {
                _pJobCount = 0;
                for (int i = 0; i < PJobListAll.Count; i++)
                {
                    _pJobCount++;
                }
                return _pJobCount;
            }
        }
        public GEM_PJob(CSecsEquip300 m_pSecs, SecsEquipHelper secsEquipHelper)
        {
            m_pName = "PJob";
            this.m_pSecs = m_pSecs;
            this.SecsEquipHelper = secsEquipHelper;
        }


        // 更新数据
        public override void UpdateData()
        {
            PJobListAll = SecsDataHelper.PJobListAll;
            PJobListByCJob = new List<ProcessJob>();

            m_pSecs.m_pPJobCreateProc += OnPJobCreate;
            SecsEquipHelper.RemoteContro.m_pPJobCreateProc += OnPJobCreate;

        }

        // 获取选中的PJobID
        string GetSelectPJobID()
        {
            return CurSelPJobID;
        }

        // 更新作业状态
        public void UpdateSelectJobState(string pPJobID, ProcessJobState nNewState)
        {
            //string pPJobID = GetSelectPJobID();
            bool updateRet = UpdateCurPJobByPJobID(pPJobID);
            if (!updateRet) return;

            if (pPJobID != null && CurSelPJob.nPRJobState != nNewState)
            {
                RcResult rc = new RcResult(0);
                if (SecsDataHelper.Function.Gem300Enable)
                {
                    rc = m_pSecs.ProcessJobStateUpdate(pPJobID, nNewState);
                }
                if (rc != 0)
                {
                    LogMsg($"Error {pPJobID} -> {nNewState.ToString()}; Res : {rc.toString()}");
                }
                else
                {
                    LogMsg($"Succ {pPJobID} -> {nNewState.ToString()}");
                }
                UpdateCurJobState(pPJobID, nNewState);
                if (CurSelPJob != null)
                {
                    CurSelPJob.nPRJobState = nNewState;
                }
                PJobStageChange?.Invoke();
                Save();
            }
        }
        private bool UpdateCurPJobByPJobID(string pPJobID)
        {
            for (int i = 0; i < PJobListAll.Count; i++)
            {
                if (PJobListAll[i].pPJobID == pPJobID)
                {
                    CurSelPJob = PJobListAll[i];
                    return true;
                }
            }
            return false;
        }
        private void UpdateCurJobState(string curSelPJobID, ProcessJobState nNewState)
        {
            for (int i = 0; i < PJobListAll.Count; i++)
            {
                if (PJobListAll[i].pPJobID == curSelPJobID)
                {
                    PJobListAll[i].nPRJobState = nNewState;
                }
            }
            for (int i = 0; i < PJobListByCJob.Count; i++)
            {
                if (PJobListByCJob[i].pPJobID == curSelPJobID)
                {
                    PJobListByCJob[i].nPRJobState = nNewState;
                }
            }

        }


        // 开始

        /// <summary>
        /// PJob 处理开始
        /// </summary>
        public void JobStart(string strPJobID)
        {
            UpdateSelectJobState(strPJobID, ProcessJobState.PROCESSING);
        }

        /// <summary>
        ///  PJob 处理完成
        /// </summary>
        public void JobComplete(string strPJobID)
        {
            UpdateSelectJobState(strPJobID, ProcessJobState.COMPLETE);
        }
        public void JobPause(string strPJobID)
        {
            UpdateSelectJobState(strPJobID, ProcessJobState.PAUSED);
        }

        public void JobResume(string strPJobID)
        {
            UpdateSelectJobState(strPJobID, ProcessJobState.PROCESSING);
        }

        public void JobStop(string strPJobID)
        {
            UpdateSelectJobState(strPJobID, ProcessJobState.STOPPED);
        }

        public void JobAbort(string strPJobID)
        {
            UpdateSelectJobState(strPJobID, ProcessJobState.ABORTED);
        }


        /// <summary>
        /// 删除所有PJob
        /// </summary>
        public void JobDeleteAll()
        {
            int count = PJobListAll.Count;
            for (int i = 0; i < count; i++)
            {
                JobDelete(PJobListAll[0].pPJobID);
            }

        }
        /// <summary>
        /// 强制删除所有PJob
        /// </summary>
        public void JobDeleteAllForce()
        {
            JobDeleteAll();
            PJobListAll.Clear();
            Save();
        }

        /// <summary>
        /// 删除一条PJob
        /// </summary>
        public void JobDelete(string pPJobID)
        {
            bool isContain = false;
            for (int i = 0; i < PJobListAll.Count; i++)
            {
                if (PJobListAll[i].pPJobID.Equals(pPJobID))
                {
                    isContain = true;
                }
            }
            if (!isContain)
            {
                return;
            }

            if (pPJobID != null)
            {
                RcResult rc = new RcResult();
                if (SecsDataHelper.Function.Gem300Enable)
                {
                    rc = m_pSecs.ProcessJobDelete(pPJobID);
                }
                if (rc != 0)
                {
                    LogMsg($"Error {pPJobID} -> Delete; Res : {rc.toString()}", MsgSource_KE.EQ);
                }
                else
                {
                    LogMsg($"Succ {pPJobID} -> Delete", MsgSource_KE.EQ);
                }
                // 更新List信息
                DeletePJobLocal(pPJobID);
            }
        }

        // 更新List信息
        internal void DeletePJobLocal(string pJobID)
        {
            for (int i = 0; i < PJobListAll.Count; i++)
            {
                string pText = PJobListAll[i].pPJobID;
                if (pText == pJobID)
                {
                    PJobListAll.RemoveAt(i);
                    break;
                }
            }
            for (int i = 0; i < PJobListByCJob.Count; i++)
            {
                string pText = PJobListByCJob[i].pPJobID;
                if (pText == pJobID)
                {
                    PJobListByCJob.RemoveAt(i);
                    break;
                }
            }
            CurSelPJobID = null;
            Save();
        }

        public void JobDeleteByRFID(string strRFID)
        {
            if (string.IsNullOrEmpty(strRFID))
            {
                return;
            }
            List<string> pJobIDlist = new List<string>();
            foreach (var pJob in PJobListAll)
            {
                if (pJob.pCarrierID == strRFID)
                {
                    pJobIDlist.Add(pJob.pPJobID);
                }
            }
            for (int i = 0; i < pJobIDlist.Count; i++)
            {
                JobDelete(pJobIDlist[i]);
            }

            SecsEquipHelper.CJob.JobDeleteByPJobList(PJobListAll.Select(pJob => pJob.pPJobID).ToList());
        }

        /// <summary>
        /// 响应Host创建 PJob
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="pPJob"></param>
        /// <returns></returns>
        [Description("PJob创建通知回调：通知用户端创建PJob")]
        public RcResult OnPJobCreate(object sender, ProcessJob pPJob)
        {
            AddOnePJob(pPJob);
            LogPjobMsg(pPJob);
            PJobStageChange?.Invoke();
            return new RcResult(0);
        }

        void AddOnePJob(ProcessJob pJob)
        {
            PJobAddComp(pJob);
            Save();
        }

        void PJobAddComp(ProcessJob pJob)
        {
            bool isExist = false;
            for (int i = 0; i < PJobListAll.Count; i++)
            {
                if (pJob.pPJobID.Equals(PJobListAll[i].pPJobID))
                {
                    PJobListAll[i] = pJob;
                    isExist = true;
                }
            }
            if (!isExist)
            {
                PJobListAll.Add(pJob);
            }

        }

        private void Save()
        {
            SecsDataHelper.PJobListDAL.Save(PJobListAll);
        }

        /// <summary>
        /// 根据CJobID获取CJob绑定的PJobID列表
        /// </summary>
        /// <returns></returns>
        List<string> GetPJobIdFromCJob(string cJobID)
        {
            ControlJob cJobCurSel = SecsEquipHelper.CJob.GetCJobByID(cJobID);

            List<string> PJobIdList = new List<string>();
            if (cJobCurSel != null)
            {
                foreach (ProcessingCtrlSpec processingCtrlSpec in cJobCurSel.listProcessingCtrlSpec)
                {
                    PJobIdList.Add(processingCtrlSpec.pPRJobID);
                }
            }
            return PJobIdList;
        }

        /// <summary>
        /// 通过PJobID获取PJob列表
        /// </summary>
        public void GetPJobListByCJobID(string cJobID)
        {
            List<string> pPJobIDList = GetPJobIdFromCJob(cJobID);

            PJobListByCJob.Clear();
            for (int i = 0; i < pPJobIDList.Count; i++)
            {
                for (int j = 0; j < PJobListAll.Count; j++)
                {
                    if (pPJobIDList[i] == PJobListAll[j].pPJobID)
                    {
                        PJobListByCJob.Add(PJobListAll[j]);
                    }
                }
            }
        }
        /// <summary>
        /// 根据CJobID获取未完成的PJobID
        /// </summary>
        /// <returns></returns>
        public string GetUseAblePJobID(string cJobID, string pCarrierID)
        {
            GetPJobListByCJobID(cJobID);
            string pCJobID = null;
            if (PJobListByCJob.Count > 0)
            {
                for (int i = 0; i < PJobListByCJob.Count; i++)
                {
                    if (PJobListByCJob[i].nPRJobState != ProcessJobState.COMPLETE && PJobListByCJob[i].pCarrierID == pCarrierID)
                    {
                        CurSelPJob = PJobListByCJob[i];
                        CurSelPJobID = PJobListByCJob[i].pPJobID;
                        pCJobID = CurSelPJob.pPJobID;
                        break;
                    }
                }
            }
            return pCJobID;
        }

        /// <summary>
        /// 是否有切换过PJob
        /// </summary>
        public bool IsDifferentPJobID { get; set; }

        /// <summary>
        /// 根据PJobID获取绑定的工单和层号，返回int类型层号
        /// </summary>
        /// <param name="pCarrierID"></param>
        /// <param name="recipe"></param>
        /// <param name="slotNOList"></param>
        public bool GetPJobInfo(string pJobID, string pCarrierID, out string recipe, out List<int> slotNOList)
        {
            recipe = null;
            slotNOList = null;

            if (PJobListByCJob.Count <= 0)
            {
                return false;
            }
            for (int i = 0; i < PJobListByCJob.Count; i++)
            {
                ProcessJob processJob = null;
                if (PJobListByCJob[i].pPJobID == pJobID && PJobListByCJob[i].pCarrierID == pCarrierID) //校验实际CarrierID和EAP下发的PJob CarrierID是否一致
                {
                    string pJobIDTemp;
                    CurSelPJob = PJobListByCJob[i];
                    pJobIDTemp = PJobListByCJob[i].pPJobID;
                    if (CurSelPJobID != pJobIDTemp)
                    {
                        IsDifferentPJobID = true;
                        CurSelPJobID = pJobIDTemp;
                    }

                    recipe = PJobListByCJob[i].pRecipe;
                    slotNOList = PJobListByCJob[i].listSlot;
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// 根据PJobID获取绑定的工单和层号，返回bool类型层号(外部判断选择的wafer是否检测完，检测完成调JobComplete()再调用次方法获取下一批工单和层号)
        /// </summary>
        /// <param name="pCarrierID"></param>
        /// <param name="recipe"></param>
        /// <param name="slotNOListBool"></param>
        public bool GetPJobInfo(string pJobID, string pCarrierID, out string recipe, out List<bool> slotNOListBool)
        {
            bool ret;
            List<int> slotNOListInt = new List<int>();
            ret = GetPJobInfo(pJobID, pCarrierID, out recipe, out slotNOListInt);
            if (ret)
            {
                slotNOListBool = UtilitiesConvert.ConvertIntListToBoolList(slotNOListInt);
                return true;
            }
            else
            {
                slotNOListBool = null;
                return false;
            }
        }

        /// <summary>
        /// 当前CJob对应的PJob是否全部完成
        /// </summary>
        /// <returns></returns>
        public bool IsPJobByCurCJobComplete(string cJobID, string pCarrierID)
        {
            GetPJobListByCJobID(cJobID);

            for (int i = 0; i < PJobListByCJob.Count; i++)
            {
                if (PJobListByCJob[i].nPRJobState != ProcessJobState.COMPLETE && PJobListByCJob[i].pCarrierID == pCarrierID)
                {
                    return false;
                }
            }
            return true;
        }

        public bool Exist(string strRFID)
        {
            bool isExist = false;
            if (string.IsNullOrEmpty(strRFID))
            {
                isExist = false;
            }
            foreach (var pJob in PJobListAll)
            {
                if (pJob.pCarrierID == strRFID)
                {
                    if (SecsEquipHelper.CJob.Exist(pJob.pPJobID))
                    {
                        isExist = true;
                    }
                }
            }
            return isExist;
        }

        private void LogPjobMsg(ProcessJob pJob)
        {
            StringBuilder sb = new StringBuilder();
            List<string> listSlot = new List<string>();
            for (int i = 0; i != pJob.listSlot.Count; i++)
            {
                listSlot.Add(pJob.listSlot[i].ToString());
            }
            string pSlot = CListOperate.listJoin(listSlot);
            string pCarrierInfo = CListOperate.listJoin(pJob.pCarrierID, pSlot);

            sb.AppendLine($"pPJobID: {pJob.pPJobID}, pRecipe: {pJob.pRecipe}, listSlot: {pCarrierInfo}, nPRJobState: {pJob.nPRJobState.ToString()}");
            string strlog = "PJob: " + sb.ToString();
            LogMsg(strlog, MsgSource_KE.EAP);
        }


    }
}
